// run: $exec < input
#include <iostream>
#include <cstring>
#include <vector>
#include <string>
#include <stack>

int const maxn = 1000;
int n, m;
std::string s;

std::vector<std::vector<int> > g;
// need for tarjan
int low[maxn], dfn[maxn], color[maxn];
bool instack[maxn];
int tick, color_tick;
std::stack<int> stk;

void tarjan(int u, int parent)
{
	low[u] = dfn[u] = ++tick;
	stk.push(u);
	instack[u] = true;
	for (int i = 0; i < (int)g[u].size(); i++) {
		int v = g[u][i];
		if (v == parent) continue;
		if (!dfn[v]) {
			tarjan(v, u);
			low[u] = std::min(low[u], low[v]);
		} else if (instack[v])
			low[u] = std::min(low[u], dfn[v]);
	}
	if (low[u] == dfn[u]) {
		int t;
		++color_tick;
		do { t = stk.top(); stk.pop(); color[t] = color_tick; } // FIXME instack[t] = false;
		while (t != u);
	}
}

void add_edge(int u, int v)
{
	g[u].push_back(v);
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin >> n >> m;
	g.resize(n * m + 1);
	std::cin >> s;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++)
			if (s[i] == '>' && j < m - 1) {
				add_edge(i * m + j, i * m + j + 1);
			} else if (s[i] == '<' && j < m - 1) {
				add_edge(i * m + j + 1, i * m + j);
			}
	}
	std::cin >> s;
	for (int j = 0; j < m; j++) {
		for (int i = 0; i < n; i++) {
			if (s[j] == 'v' && i < n - 1) {
				add_edge(i * m + j, (i + 1) * m + j);
			} else if (s[j] == '^' && i < n - 1) {
				add_edge((i + 1) * m + j, i * m + j);
			}
		}
	}
	for (int i = 0; i < n * m; i++) {
		std::memset(dfn, 0, sizeof(dfn));
		std::memset(low, 0, sizeof(low));
		tarjan(i, -1);
	}
//	std::cout << color_tick << "\n";
	std::cout << ((color_tick == n * m) ? "YES" : "NO") << "\n";
}

